home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / tools / netzwerk / tcp-ip / ipdial_v1.9 / ipdial.c < prev    next >
C/C++ Source or Header  |  1996-02-26  |  25KB  |  1,145 lines

  1. /**
  2. ***  IPDial     Script program for initializing a SLIP connection
  3. ***  Copyright  (C)   1994    Jochen Wiedmann
  4. ***
  5. ***  This program is free software; you can redistribute it and/or modify
  6. ***  it under the terms of the GNU General Public License as published by
  7. ***  the Free Software Foundation; either version 2 of the License, or
  8. ***  (at your option) any later version.
  9. ***
  10. ***  This program is distributed in the hope that it will be useful,
  11. ***  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ***  GNU General Public License for more details.
  14. ***
  15. ***  You should have received a copy of the GNU General Public License
  16. ***  along with this program; if not, write to the Free Software
  17. ***  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ***
  19. ***
  20. ***  This is the main part of the program.
  21. ***
  22. ***
  23. ***  Computer: Amiga 1200                       Compiler: Dice 3.01
  24. ***
  25. ***  Author:    Jochen Wiedmann
  26. ***             Am Eisteich 9
  27. ***             72555 Metzingen
  28. ***             Germany
  29. ***
  30. ***             Phone: (+0049) 7123 / 14881
  31. ***             Internet: wiedmann@neckar-alb.de
  32. ***
  33. ***
  34. ***  History:   V 1.1   23.11.94        Initial version
  35. ***
  36. ***             V 1.2   27.02.95        Added terminal mode
  37. ***                                     Now using ReadArgs() for
  38. ***                                     command line parsing.
  39. ***
  40. ***             V 1.3   09.03.95        Added environment variable
  41. ***                                     aupport to "send" command.
  42. ***                                     Added unit support.
  43. ***
  44. ***             V 1.4   21.04.95        Added "system" command.
  45. ***                                     Added environment variable
  46. ***                                     support to "echo" command.
  47. ***                                     Terminal mode now converts
  48. ***                                     LF to CR/LF, so that modem
  49. ***                                     recognizes commands.
  50. ***                                     (Let's hope, that will still
  51. ***                                     work for entering passwords. :-(
  52. ***
  53. ***             V 1.5   30.04.95        Added "scan" command.
  54. ***
  55. ***             V 1.6   26.06.95        "delay" command supporting
  56. ***                                     ticks; ParseString()
  57. ***                                     supporting octal characters;
  58. ***                                     "wait" command using
  59. ***                                     ParseString()
  60. ***                                     (All Suggested by Will Bow.)
  61. ***
  62. ***                                     Fixed bug in SerialSend():
  63. ***                                     *.io_Device = *.io_Unit
  64. ***
  65. ***             V 1.7   22.07.95        Added ECHO, RAW and EOF options
  66. ***                                     to "terminal" command.
  67. ***                                     (Suggested by Klaus Heinz.)
  68. ***
  69. ***                                     Added BAUD option to command
  70. ***                                     line.
  71. ***
  72. ***                                     Added "setvar" command.
  73. ***
  74. ***             v 1.8   24.11.95        Put a 10 tick delay after the
  75. ***                                     DoIO() call in DeviceIODo()
  76. ***
  77. ***             v 1.9   29.11.95        Broke Delay when using decimals
  78. ***                                     Fixed it in this release.
  79. **/
  80. #define VERSION     1
  81. #define REVISION    9
  82. #define VSTRING     "IPDial 1.9 (29.11.95)"
  83. #define VERSTAG     "\0$VER: IPDial 1.9 (29.11.95)"
  84. /**
  85. ***  Include files
  86. **/
  87. #include "IPDial.h"
  88. #include <ctype.h>
  89. #include <clib/alib_protos.h>
  90. /**
  91. ***  This structure describes one command. All commands are stored
  92. ***  in a table at the end of the file.
  93. **/
  94. struct ScriptLine;
  95. typedef VOID (*CommandFunc) (struct ScriptLine *);
  96. struct Command
  97.   CommandFunc Func;
  98.   STRPTR Name;
  99. };
  100. /**
  101. ***  Each line of the script file is stored in a structure like below.
  102. **/
  103. struct ScriptLine
  104.   struct MinNode mn;
  105.   ULONG Num;
  106.   CommandFunc CommFunc;
  107.   STRPTR Label;
  108.   STRPTR Args;
  109. };
  110. /**
  111. ***  Global variables
  112. **/
  113. LONG StatusVar;
  114.  
  115. struct MinList ScriptLineList;
  116.  
  117. struct ScriptLine *CurrentScriptLine;
  118.  
  119. const UBYTE VersTag [] = VERSTAG;
  120. const UBYTE VString [] = VSTRING;
  121.  
  122. ULONG EchoMode = FALSE;
  123. ULONG VerboseMode = FALSE;
  124.  
  125. STRPTR SerialDeviceName = NULL;
  126.  
  127. struct RDArgs *MainRDArgs = NULL;
  128. /**
  129. ***  This function is used to skip blanks.
  130. **/
  131. STRPTR SkipBlanks(const UBYTE *ptr)
  132.   while(*ptr == ' '  ||  *ptr == '\t')
  133.   { 
  134.     ++ptr;
  135.   }
  136.   return((STRPTR) ptr);
  137. }
  138. /**
  139. ***  This function is used to parse a string for characters
  140. ***  like '\r' or '\n'. $VAR or ${VAR} may be used to insert
  141. ***  the value of environment variable VAR, $$ may be used to
  142. ***  insert the '$' character itself, likewise \\.
  143. ***
  144. ***  Returns a pointer to a string allocated with malloc().
  145. ***  It is the task of the caller, to free() this string.
  146. **/
  147. STRPTR ParseString(const UBYTE *ptr)
  148.   STRPTR result;
  149.   STATIC APTR parseBuffer = NULL;
  150.   /**
  151.   ***  Be sure, that buffer is valid.
  152.   **/
  153.   if (!parseBuffer  &&  !(parseBuffer = BufferCreate()))
  154.   { 
  155.     perror("malloc");
  156.     exit(10);
  157.   }
  158.   /**
  159.   ***  Clear the buffer.
  160.   **/
  161.   BufferClear(parseBuffer);
  162.  
  163.   while(*ptr)
  164.   { 
  165.     if (*ptr == '\\')
  166.     { 
  167.       ++ptr;
  168.       switch(*ptr)
  169.       { 
  170.         case 'r':
  171.             BufferExtend(parseBuffer, (STRPTR) "\r", 1);
  172.             break;
  173.           case 'n':
  174.             BufferExtend(parseBuffer, (STRPTR) "\n", 1);
  175.             break;
  176.           case '0':
  177.           case '1':
  178.           case '2':
  179.           case '3':
  180.           case '4':
  181.           case '5':
  182.           case '6':
  183.           case '7':
  184.             { 
  185.             char c;
  186.  
  187.               c = *ptr - '0';
  188.               if (ptr[1] >= '0'  &&  ptr[1] <= '7')
  189.               { 
  190.               c = (c << 3) + *(++ptr) - '0';
  191.                 if (ptr[1] >= '0'  &&  ptr[2] <= '7')
  192.                 { 
  193.                 c = (c << 3) + *(++ptr) - '0';
  194.                 }
  195.               }
  196.               BufferExtend(parseBuffer, (STRPTR) &c, 1);
  197.             }
  198.             break;
  199.           default:
  200.             BufferExtend(parseBuffer, ptr, 1);
  201.             break;
  202.       }
  203.       ++ptr;
  204.     }
  205.     else if (*ptr == '$')
  206.     { 
  207.       ++ptr;
  208.       if (*ptr == '$')
  209.       { 
  210.         BufferExtend(parseBuffer, (STRPTR) "$", 1);
  211.           ++ptr;
  212.       }
  213.       else
  214.       { 
  215.         char *varName;
  216.           const char* varPtr;
  217.           size_t varLen = 0;
  218.  
  219.           if (*ptr == '{')
  220.           { 
  221.           ++ptr;
  222.             varPtr = (const char*) ptr;
  223.             while (*ptr && *ptr != '}')
  224.             { 
  225.             ++ptr;
  226.               ++varLen;
  227.             }
  228.             if (*ptr == '}')
  229.             { 
  230.             ++ptr;
  231.             }
  232.           }
  233.           else
  234.           { 
  235.           varPtr = (const char*) ptr;
  236.             while (*ptr  &&  isalnum(*ptr))
  237.             { 
  238.             ++ptr;
  239.               ++varLen;
  240.             }
  241.           }
  242.  
  243.           if (!(varName = malloc(varLen + 1)))
  244.           { 
  245.           perror("malloc");
  246.             exit(10);
  247.           }
  248.           strncpy(varName, varPtr, varLen);
  249.           varName[varLen] = '\0';
  250.  
  251.           if ((varPtr = getenv(varName)))
  252.           { 
  253.           BufferExtend(parseBuffer, (STRPTR) varPtr, strlen(varPtr));
  254.           }
  255.       }
  256.     }
  257.     else
  258.     { 
  259.       BufferExtend(parseBuffer, ptr, 1);
  260.       ++ptr;
  261.     }
  262.   }
  263.  
  264.   BufferExtend(parseBuffer, (STRPTR) "", 1);
  265.  
  266.   if (!(result = (STRPTR) strdup((char*) BufferBuffer(parseBuffer))))
  267.   { 
  268.     perror("malloc");
  269.     exit(10);
  270.   }
  271.  
  272.   return(result);
  273. }
  274. /**
  275. ***  This is an empty function. Just to allow lines with labels only.
  276. **/
  277. VOID NoneFunc(struct ScriptLine *line)
  278. {
  279. }
  280. /**
  281. ***  This is the echo function.
  282. **/
  283. VOID EchoFunc(struct ScriptLine *line)
  284.   STRPTR *args;
  285.   int i;
  286.  
  287.   if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
  288.   { 
  289.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  290.     exit(10);
  291.   }
  292.  
  293.   for(i = 0;  *args;  ++i, ++args)
  294.   { 
  295.     char *str;
  296.  
  297.     if (i)
  298.     { 
  299.       putchar(' ');
  300.     }
  301.     str = (char*) ParseString(*args);
  302.     fputs((char *) str, stdout);
  303.     fflush(stdout);
  304.     free(str);
  305.   }
  306. }
  307. /**
  308. ***  This is the device function.
  309. **/
  310. VOID DeviceFunc(struct ScriptLine *line)
  311.   struct
  312.   { 
  313.     STRPTR Device;
  314.     STRPTR Protocol;
  315.     LONG *Unit;
  316.   } args;
  317.  
  318.   if (SerialDeviceName)
  319.   { 
  320.     fprintf(stderr, "Line %ld: Device already open, ignoring.\n", line->Num);
  321.   }
  322.  
  323.   args.Unit = NULL;
  324.   args.Device = NULL;
  325.   args.Protocol = NULL;
  326.  
  327.   if (!StrReadArgs(line->Args, (LONG *) &args,
  328.           (STRPTR) "DEVICE,PROTOCOL,UNIT/K/N"))
  329.   { 
  330.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  331.     exit(10);
  332.   }
  333.  
  334.   if (!args.Device)
  335.   { 
  336.     fprintf(stderr, "Line %ld: Missing device name.\n", line->Num);
  337.     exit(10);
  338.   }
  339.   if (!(SerialDeviceName = (STRPTR) strdup((char *) args.Device)))
  340.   { 
  341.     perror("malloc");
  342.     exit(10);
  343.   }
  344.  
  345.   if (VerboseMode)
  346.   { 
  347.     printf("DeviceFunc: Opening %s.\n", args.Device);
  348.   }
  349.  
  350.   if (!SerialOpen(args.Device, args.Protocol, args.Unit ? *args.Unit : 0))
  351.   { 
  352.     fprintf(stderr, "Line %ld: Unknown protocol.\n", line->Num);
  353.     exit(10);
  354.   }
  355. }
  356. /**
  357. ***  This function is used to set the serial.device parameters.
  358. **/
  359. VOID SetFunc(struct ScriptLine *line)
  360.   struct
  361.   { 
  362.     ULONG *Baud;
  363.     ULONG *DataBits;
  364.     ULONG *StopBits;
  365.     ULONG *BufSize;
  366.     STRPTR Parity;
  367.     STRPTR Protocol;
  368.   } args;
  369.  
  370.   if (!SerialDeviceName)
  371.   { 
  372.     fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
  373.     exit(10);
  374.   }
  375.  
  376.   args.Baud = NULL;
  377.   args.DataBits = NULL;
  378.   args.StopBits = NULL;
  379.   args.BufSize = NULL;
  380.   args.Parity = NULL;
  381.   args.Protocol = NULL;
  382.  
  383.   if (!(StrReadArgs(line->Args, (LONG *) &args,
  384.           (STRPTR) "BAUD/K/N,DATABITS/K/N,STOPBITS/K/N,BUFSIZE/K/N,"
  385.           "PARITY/K,PROTOCOL/K")))
  386.   { 
  387.     fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
  388.     exit(10);
  389.   }
  390.  
  391.   if (args.Baud)
  392.   { 
  393.     SerialSetBaud(*args.Baud);
  394.   }
  395.   if (args.DataBits)
  396.   { 
  397.     SerialSetDataBits(*args.DataBits);
  398.   }
  399.   if (args.StopBits)
  400.   { 
  401.     SerialSetStopBits(*args.StopBits);
  402.   }
  403.   if (args.BufSize)
  404.   { 
  405.     SerialSetBufSize(*args.BufSize);
  406.   }
  407.   if (args.Parity)
  408.   {
  409.     if (!SerialSetParity(args.Parity))
  410.     { 
  411.       fprintf(stderr, "Line %ld: Unknown parity.\n", line->Num);
  412.       exit(10);
  413.     }
  414.   }
  415.   if (args.Protocol)
  416.   {
  417.     if (!SerialSetProtocol(args.Protocol))
  418.     { 
  419.       fprintf(stderr, "Line %ld: Unknown protocol.\n", line->Num);
  420.       exit(10);
  421.     }
  422.   }
  423.  
  424.   if (VerboseMode)
  425.   { 
  426.     printf("SetFunc: %s Parameters modified:\n\n", SerialDeviceName);
  427.     SerialShowParms();
  428.   }
  429. }
  430. /**
  431. ***  This function shows the serial.device parameters.
  432. **/
  433. VOID ShowParmsFunc(struct ScriptLine *line)
  434.   if (!SerialDeviceName)
  435.   { 
  436.     fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
  437.     exit(10);
  438.   }
  439.  
  440.   printf("%s Parameters:\n\n", SerialDeviceName);
  441.   SerialShowParms();
  442. }
  443. /**
  444. ***  This function sends a string to the serial.device.
  445. **/
  446. VOID SendFunc(struct ScriptLine *line)
  447.   STRPTR *args;
  448.  
  449.   if (VerboseMode)
  450.   { 
  451.     fflush(stdout);
  452.     printf("\nSendFunc: Sending: ");
  453.   }
  454.  
  455.  
  456.   if (!SerialDeviceName)
  457.   { 
  458.     fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
  459.     exit(10);
  460.   }
  461.  
  462.   if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
  463.   { 
  464.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  465.     exit(10);
  466.   }
  467.  
  468.   for(;  *args;  args++)
  469.   { 
  470.     STRPTR send = ParseString(*args);
  471.  
  472.     if (VerboseMode)
  473.       printf(" %s \n", send);
  474.       
  475.     SerialSend(send, strlen((char *) send));
  476.     free(send);
  477.   }
  478.  
  479.   if (VerboseMode)
  480.   { 
  481.     printf("\n");
  482.   }
  483. }
  484. /**
  485. ***  This is similar to "if".
  486. **/
  487. VOID DoGoto(STRPTR Label, int Num)
  488.   struct ScriptLine *sl;
  489.  
  490.   for(sl = (struct ScriptLine *) ScriptLineList.mlh_Head;
  491.         sl->mn.mln_Succ;
  492.         sl = (struct ScriptLine *) sl->mn.mln_Succ)
  493.   { 
  494.     if (sl->Label  &&  strcmp((char *) sl->Label, (char *) Label) == 0)
  495.     { 
  496.       CurrentScriptLine = (struct ScriptLine *) sl->mn.mln_Pred;
  497.       return;
  498.     }
  499.   }
  500.  
  501.   fprintf(stderr, "Line %d: Unknown label.\n", Num);
  502.   exit(10);
  503. }
  504. VOID OnFunc(struct ScriptLine *line)
  505. { STRPTR ptr = line->Args;
  506.  
  507.   if (strnicmp((char *) ptr, "status", 6) == 0)
  508.   { 
  509.     ptr = SkipBlanks(ptr+6);
  510.     if (strnicmp((char *) ptr, "goto", 4) == 0)
  511.     { 
  512.       STRPTR *labels;
  513.       int i;
  514.  
  515.       if (!StrReadArgs(ptr+4, (LONG *) &labels, (STRPTR) "LABELS/M"))
  516.       { 
  517.         fprintf(stderr, "Line %ld: Memory error.\n", line->Num);
  518.           exit(10);
  519.       }
  520.       for (i = -1;  *labels;  ++i, ++labels)
  521.       { 
  522.         if (i == StatusVar)
  523.           { 
  524.           DoGoto(*labels, line->Num);
  525.             return;
  526.           }
  527.       }
  528.       return;
  529.     }
  530.   }
  531.  
  532.   fprintf(stderr, "Line %ld: Condition syntax.", line->Num);
  533.   exit(10);
  534. }
  535. /**
  536. ***  This function waits for certain strings.
  537. **/
  538. VOID WaitFunc(struct ScriptLine *line)
  539.   struct
  540.   { 
  541.     STRPTR *WaitArgs;
  542.     ULONG *TimeOut;
  543.   } args;
  544.   STRPTR* parsedArgs;
  545.   LONG TimeOut;
  546.   int i = 0;
  547.  
  548.   if(VerboseMode)
  549.     printf("\nWaitFunc: line->Args %s \n",line->Args);
  550.     
  551.   if (!SerialDeviceName)
  552.   { 
  553.     fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
  554.     exit(10);
  555.   }
  556.  
  557.   args.WaitArgs = NULL;
  558.   args.TimeOut = NULL;
  559.  
  560.   if (!(StrReadArgs(line->Args, (LONG *)&args, (STRPTR) "ARGS/M,TIMEOUT/N/K")))
  561.   { 
  562.     fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
  563.     exit(10);
  564.   }
  565.  
  566.   if (!args.WaitArgs)
  567.   { 
  568.     fprintf(stderr, "Line %ld: Missing argument.\n", line->Num);
  569.     exit(10);
  570.   }
  571.   if (!args.TimeOut)
  572.   { 
  573.     fprintf(stderr, "Line %ld: Missing timeout argument.\n", line->Num);
  574.     exit(10);
  575.   }
  576.   TimeOut = *args.TimeOut;
  577.  
  578.  
  579.   while (args.WaitArgs[i])
  580.   { 
  581.     ++i;
  582.   }
  583.  
  584.   if (!(parsedArgs = malloc(sizeof(STRPTR) * (i+1))))
  585.   { 
  586.     perror("malloc");
  587.     exit(10);
  588.   }
  589.  
  590.   for (i = 0;  args.WaitArgs[i];  i++)
  591.   { 
  592.     parsedArgs[i] = ParseString(args.WaitArgs[i]);
  593.   }
  594.   parsedArgs[i] = NULL;
  595.    
  596.   StatusVar = SerialWait(parsedArgs, TimeOut);
  597. }
  598. /**
  599. ***  The delay function waits for a certain amount of time.
  600. **/
  601. VOID DelayFunc(struct ScriptLine *line)
  602.   ULONG tics;
  603.   double ftics;
  604.   
  605.   if (VerboseMode)
  606.     printf("DelayFunc: line->Args: %s\n",(char *) line->Args);
  607.     
  608.   ftics = (atof((char *) line->Args) * 50);
  609.  
  610.   tics = (ULONG)ceil(ftics);
  611.   
  612.   if (tics == 0)
  613.   { 
  614.     fprintf(stderr, "DelayFunc: Line %ld: Missing argument.\n", line->Num);
  615.     exit(10);
  616.   }
  617.  
  618.   Delay(tics);
  619. }
  620. /**
  621. ***  And this is the Exit function.
  622. **/
  623. VOID ExitFunc(struct ScriptLine *line)
  624.  
  625.   LONG result = atol((char *) line->Args);
  626.   exit(result);
  627. }
  628. /**
  629. ***  The Goto command
  630. **/
  631. VOID GotoFunc(struct ScriptLine *line)
  632.   STRPTR Label;
  633.  
  634.   if (!(StrReadArgs(line->Args, (LONG *) &Label, (STRPTR) "LABEL/A")))
  635.   { 
  636.     fprintf(stderr, "Line %ld: Missing argument or memory error.\n",
  637.               line->Num);
  638.     exit(10);
  639.   }
  640.   DoGoto(Label, line->Num);
  641. }
  642. /**
  643. ***  This function enters terminal mode.
  644. **/
  645. VOID TermFunc(struct ScriptLine *line)
  646.   struct
  647.   { 
  648.     STRPTR eof;
  649.     ULONG noecho;
  650.     ULONG raw;
  651.   } args;
  652.  
  653.   args.eof = NULL;
  654.   args.noecho = FALSE;
  655.   args.raw = FALSE;
  656.  
  657.   if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "EOF,NOECHO/S,RAW/S"))
  658.   { 
  659.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  660.     exit(10);
  661.   }
  662.  
  663.   if (args.eof) 
  664.   {
  665.     args.eof = ParseString(args.eof);
  666.   }
  667.   SerialTerminal(args.eof, !args.noecho, !args.raw);
  668. }
  669. /**
  670. ***  Execute external commands.
  671. **/
  672. VOID SystemFunc(struct ScriptLine *line)
  673.   STRPTR *args;
  674.   int i, result;
  675.   char *cmd;
  676.   STATIC APTR systemBuffer = NULL;
  677.  
  678.   /**
  679.   ***  Initialize buffer.
  680.   **/
  681.   if (!systemBuffer  &&  !(systemBuffer = BufferCreate()))
  682.   { 
  683.     perror("malloc");
  684.     exit(10);
  685.   }
  686.   BufferClear(systemBuffer);
  687.  
  688.  
  689.   if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
  690.   { 
  691.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  692.     exit(10);
  693.   }
  694.  
  695.   for(i = 0;  *args;  ++i, ++args)
  696.   { 
  697.     char *str;
  698.  
  699.     if (i)
  700.     { 
  701.       BufferExtend(systemBuffer, (STRPTR) " ", 1);
  702.     }
  703.     str = (char*) ParseString(*args);
  704.     BufferExtend(systemBuffer, (STRPTR) str, strlen(str));
  705.     free(str);
  706.   }
  707.   cmd = (char*) BufferBuffer(systemBuffer);
  708.  
  709.   if (VerboseMode)
  710.   { 
  711.     printf("Executing command: \"%s\"\n", cmd);
  712.   }
  713.   result = system(cmd);
  714.   if (result)
  715.   { 
  716.     if (result > 1  &&  result < 10)  /* Warning */
  717.     { 
  718.       if (VerboseMode)
  719.       { 
  720.         printf("Returned %d.\n", result);
  721.       }
  722.     }
  723.     else
  724.     { printf("Error: Command \"%s\" returned %d.\n", cmd, result);
  725.       exit(result);
  726.     }
  727.   }
  728. }  
  729. /**
  730. ***  Scan the buffer received by the last "wait" command.
  731. **/
  732. VOID ScanFunc(struct ScriptLine *line)
  733.   struct
  734.   { 
  735.     STRPTR format;
  736.     ULONG global;
  737.     ULONG save;
  738.   } args;
  739.   ULONG flags;
  740.  
  741.   args.format = NULL;
  742.   args.global = FALSE;
  743.   args.save = FALSE;
  744.  
  745.   if (!(StrReadArgs(line->Args, (LONG *) &args,
  746.           (STRPTR) "FORMAT/A,GLOBAL/S,SAVE/S")))
  747.   { 
  748.     fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
  749.     exit(10);
  750.   }
  751.  
  752.   flags = 0;
  753.   if (args.save)
  754.   { 
  755.     args.global = TRUE;
  756.     flags |= GVF_SAVE_VAR;
  757.   }
  758.   if (args.global)
  759.   { 
  760.     flags |= GVF_GLOBAL_ONLY;
  761.   }
  762.   else
  763.   { 
  764.     flags |= GVF_LOCAL_ONLY;
  765.   }
  766.  
  767.   StatusVar = Vsscanf(SerialWaitBuffer(), args.format, flags);
  768. }
  769. /**
  770. ***  The SetVar command
  771. **/
  772. void SetVarFunc(struct ScriptLine *line)
  773.   struct 
  774.   {
  775.     STRPTR name;
  776.     STRPTR value;
  777.     ULONG global;
  778.     ULONG save;
  779.   } args;
  780.   int flags;
  781.  
  782.   args.name = NULL;
  783.   args.value = NULL;
  784.   args.global = FALSE;
  785.   args.save = FALSE;
  786.  
  787.   if (!(StrReadArgs(line->Args, (LONG *) &args,
  788.           (STRPTR) "NAME/A,VALUE/A,LOCALONLY/S,GLOBALONLY/S,SAVE/S")))
  789.   { 
  790.     fprintf(stderr, "Line %ld: Missing argument or memory error.\n",
  791.              line->Num);
  792.     exit(10);
  793.   }
  794.  
  795.   flags = 0;
  796.   if (args.save) 
  797.   {
  798.     flags |= GVF_SAVE_VAR;
  799.     args.global = TRUE;
  800.   }
  801.   if (args.global) 
  802.   {
  803.     flags |= GVF_GLOBAL_ONLY;
  804.   } 
  805.   else 
  806.   {
  807.     flags |= GVF_LOCAL_ONLY;
  808.   }
  809.  
  810.   setvar(args.name, args.value, LV_VAR|flags);
  811. }
  812. /**
  813. ***  This is the command table.
  814. **/
  815. struct Command CommandTab[] =
  816. { { EchoFunc,       (STRPTR) "echo"         },
  817.   { DeviceFunc,     (STRPTR) "device"       },
  818.   { SetFunc,        (STRPTR) "set"          },
  819.   { ShowParmsFunc,  (STRPTR) "showparms"    },
  820.   { SendFunc,       (STRPTR) "send"         },
  821.   { OnFunc,         (STRPTR) "on"           },
  822.   { WaitFunc,       (STRPTR) "wait"         },
  823.   { DelayFunc,      (STRPTR) "delay"        },
  824.   { ExitFunc,       (STRPTR) "exit"         },
  825.   { GotoFunc,       (STRPTR) "goto"         },
  826.   { TermFunc,       (STRPTR) "terminal"     },
  827.   { SystemFunc,     (STRPTR) "system"       },
  828.   { ScanFunc,       (STRPTR) "scan"         },
  829.   { SetVarFunc,     (STRPTR) "setvar"       },
  830.   { NULL,           NULL                    }
  831. };
  832. /**
  833. ***  This function is used to process the file. Rather easy,
  834. ***  isn't it? :-)
  835. **/
  836. VOID ProcessFile(VOID)
  837.   for(CurrentScriptLine = (struct ScriptLine *) ScriptLineList.mlh_Head;
  838.       CurrentScriptLine->mn.mln_Succ;
  839.       CurrentScriptLine = (struct ScriptLine *) CurrentScriptLine->mn.mln_Succ)
  840.   { 
  841.     (*CurrentScriptLine->CommFunc)(CurrentScriptLine);
  842.   }
  843. }
  844. /**
  845. ***  This function reads and parses the file.
  846. **/
  847. VOID ParseFile(STRPTR file)
  848.   FILE *fp;
  849.   STATIC UBYTE buffer[4096];
  850.   ULONG linenum = 0;
  851.   ULONG success = TRUE;
  852.  
  853.   if (!(fp = fopen((char *) file, "r")))
  854.   { 
  855.     fprintf(stderr, "Could not open %s for reading.\n", file);
  856.     exit(10);
  857.   }
  858.  
  859.   NewList((struct List *) &ScriptLineList);
  860.  
  861.   while(fgets((char *) buffer, sizeof(buffer), fp))
  862.   { 
  863.     ULONG len = strlen((char *) buffer);
  864.     STRPTR line;
  865.     STRPTR Label = NULL;
  866.     CommandFunc CommFunc;
  867.  
  868.     ++linenum;
  869.  
  870.     if (buffer[len-1] != '\n')
  871.     { 
  872.       fprintf(stderr, "Line %ld too long.\n", linenum);
  873.       exit(10);
  874.     }
  875.  
  876.     if (!(line = malloc(len+1)))
  877.     { 
  878.       perror("malloc");
  879.       exit(10);
  880.     }
  881.     strcpy((char*) line, (char*) buffer);
  882.     
  883.     line = SkipBlanks(line);
  884.  
  885.     /**
  886.     ***  Check for a label
  887.     **/
  888.     { 
  889.       STRPTR ptr = line;
  890.  
  891.       if (isalpha(*ptr))
  892.       { 
  893.         do
  894.           { 
  895.           ++ptr;
  896.           }
  897.           while(isalnum(*ptr));
  898.  
  899.           if (*ptr == ':')
  900.           { 
  901.           *ptr = '\0';
  902.             Label = line;
  903.             line = SkipBlanks(ptr+1);
  904.           }
  905.       }
  906.     }
  907.  
  908.     /**
  909.     ***  Check for empty line or comment line
  910.     **/
  911.     if (*line == ';'  ||  *line == '\r'  ||  *line == '\n')
  912.     { 
  913.       CommFunc = NoneFunc;
  914.       if (!Label)
  915.       { 
  916.         continue;
  917.       }
  918.     }
  919.  
  920.     /**
  921.     ***  If no empty line: Check for command
  922.     **/
  923.     else
  924.     { 
  925.       struct Command *comm;
  926.  
  927.       for (comm = &CommandTab[0];  comm->Func;  ++comm)
  928.       { 
  929.         ULONG len = strlen((char *) comm->Name);
  930.  
  931.           if (strnicmp((char *) comm->Name, (char *) line, len) == 0  &&
  932.              (line[len] == ' '  ||  line[len] == '\t'  ||
  933.               line[len] == '\r' ||  line[len] == '\n'))
  934.           { 
  935.           line = SkipBlanks(line+len);
  936.             CommFunc = comm->Func;
  937.             break;
  938.           }
  939.       }
  940.  
  941.       if (!comm->Func)
  942.       { 
  943.         fprintf(stderr, "Line %ld: Unknown command.\n", linenum);
  944.           success = FALSE;
  945.       }
  946.     }
  947.  
  948.     /**
  949.     ***  Allocate a new scriptline structure.
  950.     **/
  951.     { 
  952.       struct ScriptLine *sl;
  953.  
  954.       if (!(sl = malloc(sizeof(*sl))))
  955.       { 
  956.         perror("malloc");
  957.           exit(10);
  958.       }
  959.  
  960.       AddTail((struct List *) &ScriptLineList, (struct Node *) sl);
  961.       sl->Num = linenum;
  962.       sl->CommFunc = CommFunc;
  963.       sl->Args = line;
  964.       sl->Label = Label;
  965.       /*
  966.       if(VerboseMode)
  967.       {
  968.         printf("\n");
  969.         printf("ParseFile: Num      %d  \n", sl->Num);
  970.         printf("ParseFile: CommFunc 0x%x\n", sl->CommFunc);
  971.         printf("ParseFile: Args     %s  \n", sl->Args);
  972.         printf("ParseFile: Label    %s  \n", sl->Label);
  973.       }
  974.       */
  975.     }
  976.   }
  977.  
  978.   if (ferror(fp))
  979.   { 
  980.     perror("fgets");
  981.     exit(10);
  982.   }
  983.  
  984.   if (!success)
  985.   { 
  986.     exit(10);
  987.   }
  988.  
  989.   fclose(fp);
  990. }
  991. /**
  992. ***  This is the Cleanup() function, called, when the program terminates.
  993. **/
  994. VOID Cleanup(VOID)
  995.   SerialCleanup();
  996.   StrReadArgsFree();
  997.   if (MainRDArgs)
  998.   { 
  999.     FreeArgs(MainRDArgs);
  1000.   }
  1001. }
  1002. /**
  1003. ***  This function hints about the GPL.
  1004. **/
  1005. VOID ShowGPL(FILE *fp)
  1006.   fprintf(fp, "This program is governed by the terms and conditions of the\n");
  1007.   fprintf(fp, "GNU General Public License. A copy should have come with\n");
  1008.   fprintf(fp, "this distribution. (See the file COPYING.) In that license\n");
  1009.   fprintf(fp, "it is made clear that you are welcome to redistribute either\n");
  1010.   fprintf(fp, "verbatim or modified copies of the program and the documentation\n");
  1011.   fprintf(fp, "under certain conditions. Further you are told that this program\n");
  1012.   fprintf(fp, "comes with ABSOLUTELY NO WARRANTY!\n");
  1013. }
  1014. /**
  1015. ***  This function displays the Usage() message.
  1016. **/
  1017. VOID Usage(VOID)
  1018.   fprintf(stderr, "Usage: IPDial SCRIPT,DEVICE/K,PROTOCOL/K,TERMINAL/S,ECHO/S,VERBOSE/S,HELP/S\n\n");
  1019.   fprintf(stderr, "\tSCRIPT:    Script file to execute.\n");
  1020.   fprintf(stderr, "\tDEVICE:    Device to use (default serial.device)\n");
  1021.   fprintf(stderr, "\tPROTOCOL:  Protocol to use; XONXOFF, 7WIRE (default) or NONE)\n");
  1022.   fprintf(stderr, "\tUNIT:      Unit to use (default 0)\n");
  1023.   fprintf(stderr, "\tECHO:      Show modems replies.\n");
  1024.   fprintf(stderr, "\tVERBOSE:   Be verbose.\n\n");
  1025.   fprintf(stderr, "\tTERMINAL:  Run in terminal mode.\n");
  1026.   fprintf(stderr, "\tHELP:      Print this message.\n");
  1027.   fprintf(stderr, "\n\n%s  @ 1994 by Jochen Wiedmann\n\n", VString);
  1028.   ShowGPL(stderr);
  1029.   exit(5);
  1030. }
  1031. /**
  1032. ***  This is main().
  1033. **/
  1034. int main(int argc, char *argv[])
  1035.   struct
  1036.   { 
  1037.     STRPTR file;
  1038.     STRPTR device;
  1039.     STRPTR protocol;
  1040.     LONG *unit;
  1041.     LONG *baud;
  1042.     ULONG terminal;
  1043.     ULONG help;
  1044.     ULONG echo;
  1045.     ULONG verbose;
  1046.     ULONG raw;
  1047.   } args;
  1048.  
  1049.   args.file = NULL;
  1050.   args.device = (STRPTR) "serial.device";
  1051.   args.protocol = (STRPTR) "7wire";
  1052.   args.unit = NULL;
  1053.   args.baud = NULL;
  1054.   args.terminal = FALSE;
  1055.   args.echo = FALSE;
  1056.   args.verbose = FALSE;
  1057.   args.help = FALSE;
  1058.   args.raw = FALSE;
  1059.  
  1060.   if (!argc)    /*  No WB handling.     */
  1061.   { 
  1062.     exit(-1);
  1063.   }
  1064.  
  1065.   if (atexit(Cleanup))
  1066.   { 
  1067.     fprintf(stderr, "Memory error.\n");
  1068.     exit(20);
  1069.   }
  1070.  
  1071.   if (!(MainRDArgs = ReadArgs((STRPTR) "SCRIPT,DEVICE/K,PROTOCOL/K,"
  1072.                                            "UNIT/K/N,BAUD/K/N,TERMINAL/S,"
  1073.                                              "HELP/S,ECHO/S,VERBOSE/S,RAW/S",
  1074.                                               (LONG *) &args, NULL)))
  1075.   { 
  1076.     fprintf(stderr, "Cannot parse command line.\n");
  1077.   }
  1078.  
  1079.   if (args.help  || (!args.file  &&  !args.terminal))
  1080.   { 
  1081.     Usage();
  1082.   }
  1083.  
  1084.   EchoMode = args.echo;
  1085.   if (args.verbose)
  1086.   { 
  1087.     VerboseMode = TRUE;
  1088.     printf("%s  @ 1994 by Jochen Wiedmann\n\n", VString);
  1089.     ShowGPL(stdout);
  1090.     printf("\n\n");
  1091.   }
  1092.  
  1093.   if (args.terminal)
  1094.   { 
  1095.     if(VerboseMode)
  1096.       printf("\nMain: %d\n",__LINE__);
  1097.       
  1098.     SerialOpen(args.device, args.protocol, args.unit ? *args.unit : 0);
  1099.     if (args.baud)
  1100.     { 
  1101.       if(VerboseMode)
  1102.         printf("\nMain: %d\n",__LINE__);
  1103.       SerialSetBaud(*args.baud);
  1104.     }
  1105.     if(VerboseMode)
  1106.       printf("\nMain: %d\n",__LINE__);
  1107.     SerialTerminal(NULL, TRUE, !args.raw);
  1108.   }
  1109.   else if (args.file)
  1110.   { 
  1111.     if(VerboseMode)
  1112.       printf("\nMain: %d\n",__LINE__);
  1113.     ParseFile(args.file);
  1114.     if(VerboseMode)
  1115.       printf("\nMain: %d\n",__LINE__);
  1116.     ProcessFile();
  1117.   }
  1118.  
  1119.   exit(0);
  1120. }
  1121.